#ifndef HUZHOU_COMMON_H
#define HUZHOU_COMMON_H

#include <memory>

#include <signal.h>

#include "asr_stream.h"
#include "tts_thread.h"
#include "port_audio.h"

#include "llm_server.h"

#include "people_id_file.h"


namespace hzc {
    // ======== 和 ASR KWS TTS 相关的全局变量 （需要 c++ version > 17）========
    inline std::unique_ptr<AsrStream>  asr;
    inline std::unique_ptr<KeywordSpotter>  kws;
    inline std::unique_ptr<TtsThread>  tts;

    inline std::unique_ptr<PortAudioManager> pam;

    inline std::unique_ptr<LlmServer> lserver;

    

    inline bool exitFlag = false;

    inline constexpr int sleepPeriodMs = 300;

    inline bool audio_buffer_empty = false;

    inline void signalHandler(int signum) {
        exitFlag = true;
        sys_log("signal handler .... exit ......");

        if (tts) {
            tts->audioStop();
        }
    
        if (asr) {
            sys_log("asr pause.");
            asr->pause();
            asr->stop();
        }
    
        sys_log("ready for delete kws ......");
        if (kws)    kws.reset();

        sys_log("ready for delete asr ......");
        if (asr)    asr.reset();

        sys_log("ready for delete tts ......");
        if (tts)    tts.reset();

        sys_log("ready for delete pam ......");
        if (pam)    pam.reset();

        sys_log("ready for delete lserver ......");
        if (lserver)    lserver.reset();
    
        sys_log("All memory were deleted suceessfully :)");
        exit(signum);
        sys_log("exit successfully.");
    }


    // 进行关键词识别的回调函数
    int asr_inputStream_callback(const float* audioData, int numSamples) {
        if (hzc::kws) {
            hzc::kws->DetectKeyword(static_cast<int>(hzc::asr->sample_rate()), audioData, numSamples);
        }
        return 0;
    }


    // 等待语音播放完成
    inline void waitForTtsAudioEmpty(void) {
        // 等待 tts 文本缓冲区空，也就是语音合成只剩下最后一句了
        while (!hzc::tts->bufferEmpty() && !hzc::exitFlag) {
            sys_log("waiting for tts buffer empty......");
            std::this_thread::sleep_for(std::chrono::milliseconds(sleepPeriodMs));
        }
        sys_log("tts buffer empty!");
    
        // 设置 tts 回调函数
        hzc::tts->setBufferTransitionToEmptyCallback([]() {
            // hzc::tts->fillSilence();
            audio_buffer_empty = true;
        });
    
        // 等待语音播放完成
        while (!audio_buffer_empty && !hzc::exitFlag) {
            sys_log("waiting for audio buffer empty......");
            std::this_thread::sleep_for(std::chrono::milliseconds(sleepPeriodMs));
        }

        audio_buffer_empty = false;
    
        hzc::tts->setBufferTransitionToEmptyCallback(nullptr);
        sys_log("audio buffer empty!");
    }


    inline void init(void) {
        signal(SIGINT, signalHandler);

        // pavucontrol

        // 执行这个脚本，设置默认的输入设备 并 设定输入增益
        // int ret = system("/home/mdical/llm_node/src/llm_node/scripts/setDefaultInput.sh");
        // if (ret != 0) {
        //     err_log("set default input failed.");
        //     exit(-1);
        // }

        // 执行这个脚本，设置默认的输出设备为扬声器 并设定输出增益
        // ret = system("/home/mdical/llm_node/src/llm_node/scripts/setDefaultOutputSpeaker.sh");
        // if (ret != 0) {
        //     warn_log("set default output speaker failed.");
        // }

        // 初始化全局的 portAudio 库
        pam = std::make_unique<PortAudioManager>();

        // 初始化语音合成类
        tts = std::make_unique<TtsThread>();
        // tts->setBufferTransitionToEmptyCallback(audioBuffer_TransitionToEmpty_Callback);
        tts->fillSilence(); // 避免输出杂音
        tts->audioStart();  // 启动语音输出

        // 初始化语音识别类
        asr = std::make_unique<AsrStream>(
            "/opt/sherpa-onnx/sherpa-onnx-streaming-zipformer-bilingual-zh-en"
        );

        // 初始化关键词检测
        kws = std::make_unique<KeywordSpotter>(
            "/opt/sherpa-onnx/kws-zipformer-wenetspeech", 
            "/opt/sherpa-onnx/kws-zipformer-wenetspeech/outputMykeywords.txt");

        // 初始化实验室的大语言模型
        lserver = std::make_unique<LlmServer>();


    }
};

#endif // HUZHOU_COMMON_H
